﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace LPNRTool
{
    // 定义 UdpState类
    public class UdpState
    {
        public UdpClient udpClient;
        public IPEndPoint ipEndPoint;
        public const int BufferSize = 1024;
        public byte[] buffer = new byte[BufferSize];
        public int counter = 0;
    }

    public class AsyncSocketUDPServer
    {
        WriteLog Trace = new WriteLog();

        // 定义节点
        private IPEndPoint ipEndPoint = null;
        private IPEndPoint remoteEP = null;
        // 定义UDP发送和接收
        private UdpClient udpReceive = null;
        private UdpClient udpSend = null;
        // 定义端口
        private const int listenPort = 10040;
        private const int remotePort = 10041;
        UdpState udpReceiveState = null;
        UdpState udpSendState = null;
        // 异步状态同步
        private ManualResetEvent sendDone = new ManualResetEvent(false);
        private ManualResetEvent receiveDone = new ManualResetEvent(false);

        public AsyncSocketUDPServer()
        {
            // 本机节点
            //ipEndPoint = new IPEndPoint(IPAddress.Any, listenPort);
            ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.10.181"), listenPort);
            // 远程节点
            //remoteEP = new IPEndPoint(Dns.GetHostAddresses(Dns.GetHostName())[0], remotePort);
            remoteEP = new IPEndPoint(IPAddress.Parse("192.168.10.118"), remotePort);
            // 实例化
            udpReceive = new UdpClient(ipEndPoint);
            udpSend = new UdpClient();

            // 分别实例化udpSendState、udpReceiveState
            udpReceiveState = new UdpState();
            udpReceiveState.udpClient = udpReceive;
            udpReceiveState.ipEndPoint = ipEndPoint;

            udpSendState = new UdpState();
            udpSendState.udpClient = udpSend;
            udpSendState.ipEndPoint = remoteEP;
        }
     

        public void ReceiveMsg()
        {
            Trace.WriteLogFile("listening for messages");
            while (true)
            {
                lock (this)
                {
                    // 调用接收回调函数
                    IAsyncResult iar = udpReceive.BeginReceive(new AsyncCallback(ReceiveCallback), udpReceiveState);
                    receiveDone.WaitOne();
                    Thread.Sleep(100);
                }
            }
        }
      
        // 接收回调函数
        private void ReceiveCallback(IAsyncResult iar)
        {
            UdpState udpReceiveState = iar.AsyncState as UdpState;
            if (iar.IsCompleted)
            {
                Byte[] receiveBytes = udpReceiveState.udpClient.EndReceive(iar, ref udpReceiveState.ipEndPoint);
               
                //string receiveString = Encoding.ASCII.GetString(receiveBytes,0,receiveBytes.Length);
                string receiveString = Common.byteToHexStr(receiveBytes);
                Trace.WriteLogFile("Received:" + receiveString);
                Thread.Sleep(100);
                receiveDone.Set();
                //SendMsg();
            }
        }
        // 发送函数
        public void SendMsg(byte[] sendBytes)
        {
            udpSend.Connect(udpSendState.ipEndPoint);
            udpSendState.udpClient = udpSend;
            udpSendState.counter++;

            string message = string.Format("第{0}个UDP请求处理完成！", udpSendState.counter);
            //Byte[] sendBytes = Encoding.Unicode.GetBytes(message);
            udpSend.BeginSend(sendBytes, sendBytes.Length, new AsyncCallback(SendCallback), udpSendState);
            sendDone.WaitOne();
        }
        // 发送回调函数
        private void SendCallback(IAsyncResult iar)
        {
            UdpState udpState = iar.AsyncState as UdpState;
            Trace.WriteLogFile("第" + udpState.counter + "个请求处理完毕！");
            Trace.WriteLogFile("number of bytes sent:" + udpState.udpClient.EndSend(iar));
            sendDone.Set();
        }
      
    }

}
